<?php
namespace Tbf\Bundle\ConfigBundle;

use Symfony\Component\DependencyInjection\Container;
use Symfony\Component\EventDispatcher\EventDispatcher;
use Symfony\Component\Finder\Finder;
use Symfony\Component\Yaml\Yaml;
use Tbf\Component\FileSystem\FileSystemFunction;
use Tbf\Bundle\ConfigBundle\Exception\ConfigException;

/**
 * 更新dic以保存配置
 * 本次请求修改配置,
 * 下次请求可以在dic里面看到新的配置
 * 本次请求可以在这个对象里面看到新的配置
 */
class ConfigManager
{
    protected $container;
    protected $manage_config;
    protected $save_path;
    protected $event_dispatcher;
    public function __construct(Container $container,$save_path,EventDispatcher $event_dispatcher)
    {
        $this->container = $container;
        //更新 manage_config 的数据,保证每一个被管理的参数都有值
        foreach ($this->getManageNameList() as $name) {
            if ($container->hasParameter($name)) {
                $this->manage_config[$name] = $container->getParameter($name);
            } else {
                $this->manage_config[$name] = null;
            }
        }

        $this->save_path = $save_path;
        $this->event_dispatcher = $event_dispatcher;
    }

    /**
     * 设置参数
     * @param string $name
     * @param mixed  $value
     */
    public function setParameter($name,$value)
    {
        if (!in_array($name,$this->getManageNameList())) {
            throw new ConfigException(sprintf('try to set not manage parameter %s',$name));
        }
        //如果数据没有变化,不赋值
        if ($value===$this->manage_config[$name]) {
            return;
        }
        $this->manage_config[$name] = $value;
        $this->saveParameter();
        $this->event_dispatcher->dispatch(ConfigEventList::CONFIG_CHANGE,new ConfigChangeEvent($name,$value));
    }

    /**
     * 获取一个参数,这个地方能获得最新的参数
     * @param  string $name
     * @return mixed
     */
    public function getParameter($name)
    {
        if (in_array($name,$this->getManageNameList())) {
            return $this->manage_config[$name];
        }

        return $this->container->getParameter($name);
    }

    /**
     * 获取所有管理的参数
     */
    public function getManageParameterList()
    {
        $output = array();
        foreach ($this->getManageNameList() as $name) {
            $output[$name] = $this->manage_config[$name];
        }

        return $output;
    }

    /**
     * 管理的参数列表
     */
    public function getManageNameList()
    {
        return array(
            'alumni.birthday_email_open',
            'alumni.reply_to_email',
            'alumni.return_email',
        );
    }
    protected function saveParameter()
    {
        if (empty($this->save_path)) {
            return;
        }
        $yml_config = Yaml::dump(array('parameters'=>$this->manage_config));
        FileSystemFunction::putContent($this->save_path,$yml_config);
        //重建container缓存
        $this->resetCache();
    }

    /**
     * rm -rf ./app/cache/*
     */
    protected function resetCache()
    {
        $cache_dir = $this->getParameter('kernel.cache_dir');
        foreach (Finder::create()->depth(0)->in($cache_dir) as $path) {
            /** @var \Symfony\Component\Finder\SplFileInfo $path */
            FileSystemFunction::delete($path->getRealPath());
        }
    }
}
